import { on, off } from "@/utils/dom";
import { isMobile } from "@/utils/validate";

function defaultConditional() {
	return true;
}
export function directive(e, el, binding) {
	const handler = typeof binding.value === "function" ? binding.value : binding.value.handler;

	const isActive =
		(typeof binding.value === "object" && binding.value.closeConditional) || defaultConditional;
	if (!e || isActive(e) === false) return;
	const elements = ((typeof binding.value === "object" && binding.value.include) || (() => []))();
	elements.push(el);

	!elements.some((el) => el.contains(e.target)) &&
		setTimeout(() => {
			if (isActive(e) && el._selectRangeStatus) {
				handler && handler(false, e);
				window.getSelection
					? window.getSelection().removeAllRanges()
					: document.selection.empty();
				el._selectRangeStatus = false;
			}
		}, 0);
}

const selectRange = (e, el, binding) => {
	const handler = typeof binding.value === "function" ? binding.value : binding.value.handler;
	let range = document.createRange();
	range.selectNodeContents(el);
	let selection = window.getSelection();
	selection.removeAllRanges();
	selection.addRange(range);
	if (!el._selectRangeStatus) {
		el._selectRangeStatus = true;
		handler && handler(true, e);
	}
};
export default {
	inserted(el, binding) {
		const onClickOutside = (e) => directive(e, el, binding);
		const app = document.querySelector("[data-app]") || document.body;
		on(app, "click", onClickOutside);
		el._clickOutside = onClickOutside;

		if (!isMobile) {
			const onSelectRange = (e) => selectRange(e, el, binding);
			on(el, "click", onSelectRange);
			el._selectRange = onSelectRange;
		}
	},
	unbind(el) {
		if (el._clickOutside) {
			const app = document.querySelector("[data-app]") || document.body;
			app && off(el, "click", el._clickOutside);
			delete el._clickOutside;
		}

		if (!isMobile) {
			if (el._selectRange) {
				off(el, "click", el._selectRange);
				delete el._selectRange;
			}
		}
	}
};
